package models

import (
	"errors"
	"fmt"
	"time"

	"github.com/beego/beego/v2/client/orm"
)

// RechargeRecord 充值记录模型
type RechargeRecord struct {
	BaseModel
	MemberId    int64   `orm:"index" json:"member_id"`       // 会员ID
	OrderNo     string  `orm:"size(64)" json:"order_no"`     // 订单号
	Amount      float64 `json:"amount"`                      // 充值金额
	GiftAmount  float64 `json:"gift_amount"`                 // 赠送金额
	GiftPoints  int     `json:"gift_points"`                 // 赠送积分
	PackageId   int64   `json:"package_id"`                  // 套餐ID，0表示自定义金额
	Type        int8    `json:"type"`                        // 充值类型：1:全国通用充值, 2:单门店充值
	StoreId     int64   `orm:"index" json:"store_id"`        // 门店ID（单门店充值时使用）
	Status      int8    `json:"status"`                      // 状态：0:待支付, 1:支付成功, 2:支付失败
	PayTime     int64   `json:"pay_time"`                    // 支付时间
	PayMethod   string  `orm:"size(32)" json:"pay_method"`   // 支付方式
	Transaction string  `orm:"size(128)" json:"transaction"` // 支付交易号
	Description string  `orm:"size(255)" json:"description"` // 充值说明
}

// TableName 设置表名
func (r *RechargeRecord) TableName() string {
	return "ss_recharge_record"
}

// GetRechargeRecordById 根据ID获取充值记录
func GetRechargeRecordById(id int64) (*RechargeRecord, error) {
	record := &RechargeRecord{BaseModel: BaseModel{Id: id}}
	o := orm.NewOrm()
	err := o.Read(record)
	return record, err
}

// GetRechargeRecordByIdWithFranchise 根据ID获取充值记录（支持加盟商权限验证）
func GetRechargeRecordByIdWithFranchise(id int64, franchiseId int64) (*RechargeRecord, error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(RechargeRecord)).Filter("id", id).Filter("is_deleted", 0)

	// 加盟商过滤
	if franchiseId > 0 {
		qs = qs.Filter("franchise_id", franchiseId)
	}

	record := &RechargeRecord{}
	err := qs.One(record)
	return record, err
}

// GetRechargeRecordByOrderNo 根据订单号获取充值记录
func GetRechargeRecordByOrderNo(orderNo string) (*RechargeRecord, error) {
	if orderNo == "" {
		return nil, errors.New("订单号不能为空")
	}

	o := orm.NewOrm()
	record := &RechargeRecord{OrderNo: orderNo}
	err := o.Read(record, "OrderNo")
	return record, err
}

// GetRechargeRecordByOrderNoWithFranchise 根据订单号获取充值记录（支持加盟商权限验证）
func GetRechargeRecordByOrderNoWithFranchise(orderNo string, franchiseId int64) (*RechargeRecord, error) {
	if orderNo == "" {
		return nil, errors.New("订单号不能为空")
	}

	o := orm.NewOrm()
	qs := o.QueryTable(new(RechargeRecord)).Filter("order_no", orderNo).Filter("is_deleted", 0)

	// 加盟商过滤
	if franchiseId > 0 {
		qs = qs.Filter("franchise_id", franchiseId)
	}

	record := &RechargeRecord{}
	err := qs.One(record)
	return record, err
}

// GetRechargeRecordList 获取充值记录列表
func GetRechargeRecordList(page, pageSize int, filters map[string]interface{}) ([]*RechargeRecord, int64, error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(RechargeRecord))

	// 应用过滤条件
	if memberId, ok := filters["member_id"].(int64); ok {
		qs = qs.Filter("member_id", memberId)
	}

	if orderNo, ok := filters["order_no"].(string); ok && orderNo != "" {
		qs = qs.Filter("order_no__contains", orderNo)
	}

	if status, ok := filters["status"].(int8); ok {
		qs = qs.Filter("status", status)
	}

	if startTime, ok := filters["start_time"].(int64); ok {
		qs = qs.Filter("created_at__gte", startTime)
	}

	if endTime, ok := filters["end_time"].(int64); ok {
		qs = qs.Filter("created_at__lte", endTime)
	}

	// 加盟商过滤
	if franchiseId, ok := filters["franchise_id"].(int64); ok && franchiseId > 0 {
		qs = qs.Filter("franchise_id", franchiseId)
	}

	// 排除已删除的记录
	qs = qs.Filter("is_deleted", 0)

	// 获取总数
	total, _ := qs.Count()

	// 分页查询
	var records []*RechargeRecord
	_, err := qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&records)

	return records, total, err
}

// CreateRechargeRecord 创建充值记录
func CreateRechargeRecord(record *RechargeRecord) (int64, error) {
	if record.MemberId <= 0 {
		return 0, errors.New("会员ID无效")
	}

	if record.Amount <= 0 {
		return 0, errors.New("充值金额必须大于0")
	}

	// 生成订单号
	record.OrderNo = GenerateOrderNo("RC")
	record.Status = 0 // 待支付状态
	record.BeforeInsert()

	o := orm.NewOrm()
	id, err := o.Insert(record)
	return id, err
}

// UpdateRechargeRecord 更新充值记录
func UpdateRechargeRecord(record *RechargeRecord, fields ...string) error {
	o := orm.NewOrm()
	_, err := o.Update(record, fields...)
	return err
}

// UpdateRechargeStatus 更新充值记录状态
func UpdateRechargeStatus(orderNo string, status int8, payMethod, transaction string) error {
	if orderNo == "" {
		return errors.New("订单号不能为空")
	}

	o := orm.NewOrm()
	record := &RechargeRecord{OrderNo: orderNo}
	err := o.Read(record, "OrderNo")
	if err != nil {
		return err
	}

	record.Status = status
	record.PayMethod = payMethod
	record.Transaction = transaction
	if status == 1 {
		record.PayTime = time.Now().Unix()
	}

	_, err = o.Update(record, "Status", "PayTime", "PayMethod", "Transaction")
	return err
}

// GetMemberRechargeRecords 获取会员的充值记录
func GetMemberRechargeRecords(memberId int64, page, pageSize int, franchiseId int64) ([]*RechargeRecord, int64, error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(RechargeRecord)).Filter("member_id", memberId).Filter("is_deleted", 0)

	// 加盟商过滤
	if franchiseId > 0 {
		qs = qs.Filter("franchise_id", franchiseId)
	}

	// 获取总数
	total, _ := qs.Count()

	// 分页查询
	var records []*RechargeRecord
	_, err := qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&records)

	return records, total, err
}

// GenerateOrderNo 生成订单号
func GenerateOrderNo(prefix string) string {
	timestamp := time.Now().Format("20060102150405")
	random := time.Now().UnixNano() % 1000
	return prefix + timestamp + fmt.Sprintf("%03d", random)
}

// UpdateMemberBalanceLocal 本地版本的更新会员余额函数
func UpdateMemberBalanceLocal(memberId int64, amount float64) error {
	return UpdateMemberBalanceWithBonus(memberId, amount, 0, 0)
}

// UpdateMemberBalanceWithBonus 更新会员余额并赠送金额和积分
func UpdateMemberBalanceWithBonus(memberId int64, amount float64, giftAmount float64, giftPoints int) error {
	return UpdateMemberBalanceWithBonusAndFranchise(memberId, amount, giftAmount, giftPoints, 0)
}

// UpdateMemberBalanceWithBonusAndFranchise 更新会员余额并赠送金额和积分（支持加盟商权限验证）
func UpdateMemberBalanceWithBonusAndFranchise(memberId int64, amount float64, giftAmount float64, giftPoints int, franchiseId int64) error {
	if memberId <= 0 {
		return errors.New("会员ID无效")
	}

	if amount <= 0 {
		return errors.New("充值金额必须大于0")
	}

	// 开启事务
	o := orm.NewOrm()
	tx, err := o.Begin()
	if err != nil {
		return err
	}

	// 获取会员信息
	qs := tx.QueryTable(new(Member)).Filter("id", memberId).Filter("is_deleted", 0)

	// 加盟商过滤
	if franchiseId > 0 {
		qs = qs.Filter("franchise_id", franchiseId)
	}

	member := &Member{}
	err = qs.One(member)
	if err != nil {
		tx.Rollback()
		return err
	}

	// 更新会员余额
	member.Balance += amount + giftAmount
	member.Points += giftPoints
	member.UpdatedAt = time.Now().Unix()
	_, err = tx.Update(member, "Balance", "Points", "UpdatedAt")
	if err != nil {
		tx.Rollback()
		return err
	}

	// 创建余额变动记录
	balanceLog := &BalanceLog{
		MemberId:      memberId,
		Amount:        amount,
		Type:          1, // 1:充值增加
		BeforeBalance: member.Balance - amount - giftAmount,
		AfterBalance:  member.Balance,
		Description:   "充值增加余额",
		Operator:      "system",
	}
	_, err = tx.Insert(balanceLog)
	if err != nil {
		tx.Rollback()
		return err
	}

	// 如果有赠送金额，创建赠送余额变动记录
	if giftAmount > 0 {
		giftBalanceLog := &BalanceLog{
			MemberId:      memberId,
			Amount:        giftAmount,
			Type:          5, // 5:充值赠送
			BeforeBalance: member.Balance - giftAmount,
			AfterBalance:  member.Balance,
			Description:   "充值赠送余额",
			Operator:      "system",
		}
		_, err = tx.Insert(giftBalanceLog)
		if err != nil {
			tx.Rollback()
			return err
		}
	}

	// 如果有赠送积分，创建积分变动记录
	if giftPoints > 0 {
		pointsLog := &PointsLog{
			MemberId:     memberId,
			Points:       giftPoints,
			Type:         3, // 3:充值赠送
			Description:  "充值赠送积分",
			Operator:     "system",
			BeforePoints: member.Points - giftPoints,
			AfterPoints:  member.Points,
		}
		_, err = tx.Insert(pointsLog)
		if err != nil {
			tx.Rollback()
			return err
		}
	}

	// 提交事务
	return tx.Commit()
}
